package com.example.demo.Config; // 你的包名

import com.example.demo.security.JwtRequestFilter;
import com.example.demo.Config.PlainTextPasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Autowired
    @Qualifier("adminDetailsServiceImpl")
    private UserDetailsService adminUserDetailsService;

    @Autowired
    @Qualifier("userDetailsServiceImpl") // 假设你还有一个普通用户的 UserDetailsService
    private UserDetailsService regularUserDetailsService;

    // 这个 PasswordEncoder 将用于普通用户或其他需要 BCrypt 的地方
    @Bean
    public PasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 为管理员创建一个专门的明文 PasswordEncoder Bean
    @Bean
    @Qualifier("plainTextPasswordEncoderForAdmin") // 使用 Qualifier 区分
    public PasswordEncoder plainTextPasswordEncoderForAdmin() {
        return new PlainTextPasswordEncoder();
    }

    // Provider for Admin authentication
    @Bean
    public DaoAuthenticationProvider adminAuthenticationProvider(
            @Qualifier("adminDetailsServiceImpl") UserDetailsService adminUserDetailsService,
            @Qualifier("plainTextPasswordEncoderForAdmin") PasswordEncoder adminPasswordEncoder // <--- 注入明文 Encoder
    ) {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(adminUserDetailsService);
        // 为管理员认证提供者设置明文密码编码器
        authProvider.setPasswordEncoder(adminPasswordEncoder);
        return authProvider;
    }

    // Provider for Regular User authentication (保持使用 BCrypt)
    @Bean
    public DaoAuthenticationProvider regularUserAuthenticationProvider(
            @Qualifier("userDetailsServiceImpl") UserDetailsService regularUserDetailsService,
            @Qualifier("bCryptPasswordEncoder") PasswordEncoder defaultPasswordEncoder // <--- 注入 BCrypt Encoder
    ) {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(regularUserDetailsService);
        authProvider.setPasswordEncoder(defaultPasswordEncoder); // 普通用户使用 BCrypt
        return authProvider;
    }

    // AuthenticationManager Bean
    @Bean
    public AuthenticationManager authenticationManager(
            @Qualifier("adminAuthenticationProvider") AuthenticationProvider adminProvider,
            @Qualifier("regularUserAuthenticationProvider") AuthenticationProvider regularProvider) {
        // 确保 AuthenticationManager 知道这两个不同的 Provider
        return new ProviderManager(Arrays.asList(adminProvider, regularProvider));
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:8081"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Bean
    @Order(1)
    public SecurityFilterChain adminFilterChain(HttpSecurity http) throws Exception {
        http
                .securityMatcher("/api/admin/**")
                .csrf(csrf -> csrf.disable())
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
                .authorizeHttpRequests(authz -> authz
                        .requestMatchers(HttpMethod.POST, "/api/admin/login").permitAll()
                        .anyRequest().hasRole("ADMIN")
                )
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

    @Bean
    @Order(2)
    public SecurityFilterChain defaultFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf.disable())
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
                .authorizeHttpRequests(authz -> authz
                        .requestMatchers(HttpMethod.POST, "/api/users/register").permitAll()
                        .requestMatchers(HttpMethod.POST, "/api/users/login").permitAll()
                        .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
                        .requestMatchers("/api/users/**").authenticated() // 假设普通用户路径
                        .requestMatchers("/api/bookkeeping/**").authenticated() // 假设记账路径
                        .requestMatchers("/visit", "/today-visits", "/get-all-visits").permitAll()
                        .anyRequest().authenticated()
                )
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}
